import 'dart:math';

import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/widgets/chart/axis/combined/combined_chart.dart';
import 'package:kq_flutter_core_widget/widgets/chart/kq_chart.dart';
import 'package:get/get.dart';

/// 组合图
class CombinedChartPage extends StatelessWidget {
  const CombinedChartPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('组合图'),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          color: Colors.white,
          onPressed: Get.back,
        ),
      ),
      body: CustomScrollView(
        slivers: [
          const SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: Text(
                "主图表为柱状图(X轴,Y轴绘制根据主图来绘制)，柱状图和折线图共用一份数据：",
                style: TextStyle(fontSize: 16),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: buildBarChart(),
            ),
          ),
          const SliverToBoxAdapter(
            child: Padding(
              padding: EdgeInsets.only(top: 60),
              child: Align(
                alignment: Alignment.center,
                child: Text(
                  "主图表为柱状图(X轴,Y轴绘制根据主图来绘制)，柱状图和折线图数据独立，柱状图数据Y轴绘制参考左边的Y轴，折线图数据Y轴绘制参考右边的Y轴：",
                  style: TextStyle(fontSize: 16),
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: buildBarChart2(),
            ),
          ),
          const SliverToBoxAdapter(
            child: Padding(
              padding: EdgeInsets.only(top: 60),
              child: Align(
                alignment: Alignment.center,
                child: Text(
                  "主图表为折线图(X轴,Y轴绘制根据主图来绘制)，柱状图和折线图数据独立，Y轴数据绘制参考同一个的Y轴：",
                  style: TextStyle(fontSize: 16),
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: buildBarChart3(),
            ),
          ),
          const SliverToBoxAdapter(
            child: Padding(
              padding: EdgeInsets.only(top: 60),
              child: Align(
                alignment: Alignment.center,
                child: Text(
                  "下面为两种无数据的展示方式：",
                  style: TextStyle(fontSize: 20),
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: buildEmptyLineChart(),
            ),
          ),
          SliverToBoxAdapter(
            child: Align(
              alignment: Alignment.center,
              child: buildEmptyLineChart2(),
            ),
          ),
          const SliverToBoxAdapter(
            child: SizedBox(
              height: 100,
            ),
          ),
        ],
      ),
    );
  }

  Widget buildBarChart() {
    int xLabelCount = 6;
    double yMin = 0;
    double step = 20;
    int yLabelCount = 6;

    var colors = const [
      Colors.red,
      Colors.grey,
      Colors.green,
      Colors.deepPurpleAccent,
      Colors.teal,
      Colors.blue
    ];

    List<BarEntity> entityList = [];
    List<LineEntity> lineEntityList = [];

    for (int i = 0; i < xLabelCount; i++) {
      var value =
          yMin + Random().nextDouble() * (step * (yLabelCount - 1) - yMin);
      BarEntity entity =
          BarEntity(xIndex: i, value: value, barColors: [colors[i]]);
      entityList.add(entity);

      LineEntity lineEntity = LineEntity(
          xIndex: i,
          xIndexOffset: 0.5,
          value: value,
          labelGravity: i == 0
              ? LabelGravity.start
              : i == xLabelCount - 1
                  ? LabelGravity.end
                  : LabelGravity.center,
          labelOffset: 4,
          indicatorColor: Colors.yellow,
          drawIndicator: true);
      lineEntityList.add(lineEntity);
    }

    BarData barData = BarData(values: entityList);

    LineData lineData = LineData(
        values: lineEntityList,
        lineWidth: 2,
        lineType: LineType.liner,
        lineColors: const [
          Colors.yellow,
        ]);

    Widget result = SizedBox(
      width: 360,
      height: 240,
      child: KqChart(
        delegate: KqCombinedChartDelegate.withDefault(
            xAxis: XAxis(
              gridLineWidth: 0,
              gridUseEndPadding: true,
              labelCount: xLabelCount,
              labelMaxLines: 2,
              labelOffsetAxis: 4,
              endPadding: 11,
              labelHorizontalPadding: 10,
              axisValueFormatter: (position) =>
                  Label(value: '${position + 1}月'),
            ),
            yAxis: YAxis(
                gridLineWidth: 0.5,
                gridUseEndPadding: true,
                gridLineDash: [2, 2],
                labelMaxLines: 2,
                labelOffsetAxis: 4,
                endPadding: 11,
                labelMaxWidth: 38,
                labelMinWidth: 20,
                labelCount: yLabelCount,
                min: yMin,
                step: step),
            dataRender: CombinedChartDataRender(
                barChartDataRender: const BarChartDataRender(
                    highLightRender: BarChartHighLightRender()),
                lineChartDataRender: LineChartDataRender(
                    highLightRender: const LineChartHighLightRender(
                        lineWidth: 2, lineDash: [3, 3]))),
            gestureHandler: CombinedCharGestureHandler(
                dragEnable: false,
                lineCharGestureHandler: LineCharGestureHandler(),
                barCharGestureHandler: BarCharGestureHandler()),
            data: CombinedData(
                lineData: ChartData(
                  data: [lineData],
                ),
                barData: ChartData(data: barData, drawWithAnim: false)),
            animDuration: const Duration(seconds: 2)),
      ),
    );

    result = Padding(
      padding: const EdgeInsets.only(top: 20),
      child: result,
    );

    return result;
  }

  Widget buildBarChart2() {
    List<BarEntity> entityList = [];
    int xLabelCount = 6;
    double yMin = 0;
    double step = 20;
    int yLabelCount = 6;
    double yStepEnd = 10;

    var colors = const [
      Colors.red,
      Colors.grey,
      Colors.green,
      Colors.deepPurpleAccent,
      Colors.teal,
      Colors.blue
    ];
    for (int i = 0; i < xLabelCount; i++) {
      var value =
          yMin + Random().nextDouble() * (step * (yLabelCount - 1) - yMin);
      BarEntity entity =
          BarEntity(xIndex: i, value: value, barColors: [colors[i]]);
      entityList.add(entity);
    }

    BarData barData = BarData(values: entityList);

    List<LineEntity> lineEntityList = [];
    for (int i = 0; i < xLabelCount; i++) {
      var value =
          yMin + Random().nextDouble() * (yStepEnd * (yLabelCount - 1) - yMin);
      LineEntity entity = LineEntity(
          xIndex: i,
          xIndexOffset: 0.5,
          value: value,
          drawLabel: true,
          labelGravity: i == 0
              ? LabelGravity.start
              : i == xLabelCount - 1
                  ? LabelGravity.end
                  : LabelGravity.center,
          labelOffset: 4,
          indicatorColor: Colors.yellow,
          drawIndicator: true,
          label: '${value.toInt()}%');
      lineEntityList.add(entity);
    }

    LineData lineData = LineData(
        values: lineEntityList,
        lineWidth: 2,
        lineType: LineType.liner,
        lineColors: const [
          Colors.yellow,
        ]);

    Widget result = SizedBox(
      width: 360,
      height: 240,
      child: KqChart(
        delegate: KqCombinedChartDelegate.withDefault(
            xAxis: XAxis(
              gridLineWidth: 0,
              gridUseEndPadding: true,
              labelCount: xLabelCount,
              labelMaxLines: 2,
              labelOffsetAxis: 4,
              endPadding: 0,
              labelHorizontalPadding: 10,
              axisValueFormatter: (position) =>
                  Label(value: '${position + 1}月'),
            ),
            yAxis: YAxis(
                gridLineWidth: 0.5,
                gridUseEndPadding: false,
                gridLineDash: [2, 2],
                labelMaxLines: 2,
                labelOffsetAxis: 4,
                endPadding: 11,
                labelMaxWidth: 38,
                labelMinWidth: 20,
                labelCount: yLabelCount,
                min: yMin,
                step: step),
            yAxisEnd: YAxis(
                gridLineWidth: 0,
                labelMaxLines: 2,
                labelOffsetAxis: 4,
                endPadding: 11,
                labelMaxWidth: 38,
                labelMinWidth: 20,
                labelAlign: TextAlign.start,
                labelCount: yLabelCount,
                min: yMin,
                step: yStepEnd),
            data: CombinedData(
                lineData: ChartData(data: [lineData], yAxisType: YAxisType.end),
                barData: ChartData(data: barData, drawWithAnim: false)),
            animDuration: const Duration(seconds: 2)),
      ),
    );

    result = Padding(
      padding: const EdgeInsets.only(top: 20),
      child: result,
    );

    return result;
  }

  Widget buildBarChart3() {
    List<BarEntity> entityList = [];
    int xLabelCount = 7;
    double yMin = 0;
    double step = 20;
    int yLabelCount = 6;

    var colors = const [
      Colors.red,
      Colors.grey,
      Colors.green,
      Colors.deepPurpleAccent,
      Colors.teal,
      Colors.blue,
      Colors.blueGrey
    ];
    for (int i = 0; i < xLabelCount - 1; i++) {
      var value =
          yMin + Random().nextDouble() * (step * (yLabelCount - 1) - yMin);
      BarEntity entity =
          BarEntity(xIndex: i, value: value, barColors: [colors[i]]);
      entityList.add(entity);
    }

    BarData barData = BarData(values: entityList);
    List<LineEntity> lineEntityList = [];
    for (int i = 0; i < xLabelCount; i++) {
      var value =
          yMin + Random().nextDouble() * (step * (yLabelCount - 1) - yMin);
      LineEntity entity = LineEntity(
          xIndex: i,
          value: value,
          drawLabel: true,
          labelGravity: i == 0
              ? LabelGravity.start
              : i == xLabelCount - 1
                  ? LabelGravity.end
                  : LabelGravity.center,
          labelOffset: 4,
          indicatorColor: Colors.yellow,
          drawIndicator: true,
          label: '${value.toInt()}%');
      lineEntityList.add(entity);
    }

    LineData lineData = LineData(
        values: lineEntityList,
        lineWidth: 2,
        lineType: LineType.liner,
        lineColors: const [
          Colors.yellow,
        ]);

    Widget result = SizedBox(
      width: 360,
      height: 240,
      child: KqChart(
        delegate: KqCombinedChartDelegate.withDefault(
            mainChart: ChartType.line,
            xAxis: XAxis(
              gridLineWidth: 0,
              gridUseEndPadding: true,
              labelCount: xLabelCount,
              labelMaxLines: 2,
              labelOffsetAxis: 4,
              endPadding: 0,
              labelHorizontalPadding: 10,
              axisValueFormatter: (position) =>
                  Label(value: '${position + 1}月'),
            ),
            yAxis: YAxis(
                gridLineWidth: 0.5,
                gridUseEndPadding: false,
                gridLineDash: [2, 2],
                labelMaxLines: 2,
                labelOffsetAxis: 4,
                endPadding: 11,
                labelMaxWidth: 38,
                labelMinWidth: 20,
                labelCount: yLabelCount,
                min: yMin,
                step: step),
            data: CombinedData(
                lineData: ChartData(
                  data: [lineData],
                ),
                barData: ChartData(data: barData, drawWithAnim: false)),
            animDuration: const Duration(seconds: 2)),
      ),
    );

    result = Padding(
      padding: const EdgeInsets.only(top: 20),
      child: result,
    );

    return result;
  }

  Widget buildEmptyLineChart() {
    int xLabelCount = 8;
    double yMin = 0;
    double step = 20;
    int yLabelCount = 6;

    Widget result = SizedBox(
      width: 360,
      height: 240,
      child: KqChart(
        delegate: KqCombinedChartDelegate(
            xAxis: XAxis(
              gridLineWidth: 0.5,
              gridUseEndPadding: true,
              labelCount: xLabelCount,
              labelMaxLines: 2,
              labelOffsetAxis: 4,
              endPadding: 11,
            ),
            yAxis: YAxis(
                gridLineWidth: 0.5,
                gridUseEndPadding: true,
                labelMaxLines: 2,
                labelOffsetAxis: 4,
                endPadding: 11,
                labelMaxWidth: 38,
                labelMinWidth: 20,
                labelCount: yLabelCount,
                min: yMin,
                step: step),
            animDuration: const Duration(seconds: 2)),
      ),
    );

    result = Padding(
      padding: const EdgeInsets.only(top: 20),
      child: result,
    );

    return result;
  }

  Widget buildEmptyLineChart2() {
    Widget result = Container(
      width: 360,
      height: 240,
      color: Colors.lightBlue[200],
      child: KqChart(
        delegate: KqCombinedChartDelegate.withDefault(
          xAxis: XAxis(),
          yAxis: YAxis(),
          animDuration: const Duration(seconds: 2),
          emptyWidgetBuilder: () => const Align(
            alignment: Alignment.center,
            child: Text(
              '暂无数据',
              style: TextStyle(fontSize: 12, color: Colors.black),
            ),
          ),
        ),
      ),
    );

    result = Padding(
      padding: const EdgeInsets.only(top: 60),
      child: result,
    );

    return result;
  }
}
